home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / EVENT.C < prev    next >
Text File  |  1993-08-09  |  13KB  |  474 lines

  1. /*======================================================================*
  2. *  File Name: event.c                                                   *
  3. *  Purpose  : Some rough event handling for smtp                        *
  4. *                                                                       *
  5. *  Date          Name      Description                                  *
  6. *  ----          ----      -----------                                  *
  7. *  25-Jul-1991   DK5DC     initial                                      *
  8. *  04-Sep-1991   DK5DC     added Autorun                                *
  9. *  05-Oct-1991   DK5DC     initial 'at'                                 *
  10. *  xx-Nov-1992   DB3FL     some enhancements                            *
  11. *=======================================================================*/
  12. #include "config.h"
  13. #include <dos.h>
  14. #include <ctype.h>
  15. #include "global.h"
  16. #include "session.h"
  17. #include "socket.h"
  18. #include "usock.h"
  19. #include "netuser.h"
  20. #include "ax25.h"
  21. #include "smtp.h"
  22. #include "cmdparse.h"
  23. #include "arp.h"
  24. #include "dirutil.h"
  25. #include "commands.h"
  26. #include "event.h"
  27.  
  28. /*----------------------------------------------------------------------*
  29. * main Control block hook                                               *
  30. *-----------------------------------------------------------------------*/
  31. static Event *Delv = NULL;
  32. struct proc *Eproc = NULLPROC;
  33.  
  34. #define MINSPERDAY    1440
  35.  
  36. int EVwait = 0;
  37. int EMinute = 0;
  38.  
  39. static char *Dsstring[] = {
  40.     "Window","Suspended","Auto","Running","Autorun",
  41.     "Autowait","OneShot","Interval",
  42. };
  43.  
  44. /*----------------------------------------------------------------------*
  45. *  This subroutine is called from within smtptick. It checks the       *
  46. *  destination address against the control blocks to decide wether      *
  47. *  sending mail is allowed or not.                                      *
  48. *-----------------------------------------------------------------------*/
  49. int
  50. testdelv(int32 dest)
  51. {
  52. Event *ep;
  53. int found = FALSE;
  54.  
  55.    for(ep = Delv; ep; ep = ep->next) {
  56.       if(ep->host == dest) {
  57.          found = TRUE;
  58.          if(ep->state == Running) {
  59.              return TRUE;
  60.          }
  61.          break;
  62.       }
  63.    }
  64.    if(found) {
  65.       return FALSE;
  66.    }
  67.    return TRUE;                      /* target not in list, kick anyway*/
  68. }
  69.  
  70. /*----------------------------------------------------------------------*
  71. * Check for open tcp connctions                                         *
  72. *-----------------------------------------------------------------------*/
  73. static struct tcb * near
  74. check_tcp(Event *ep)
  75. {
  76.     struct tcb *tcb;
  77.  
  78.     for(tcb = Tcbs; tcb != NULLTCB; tcb = tcb->next) {
  79.         if(tcb->conn.remote.address == ep->host &&
  80.           tcb->conn.remote.port == ep->port) {
  81.             return tcb;
  82.         }
  83.     }
  84.     return 0;
  85. }
  86.  
  87. /*----------------------------------------------------------------------*
  88. * retrieve the Event block whose segment address is passed              *
  89. *-----------------------------------------------------------------------*/
  90. static Event * near
  91. getep(int argc,char **argv,int flag)
  92. {
  93. Event *ep, *epr = (Event *)shtop(argv[1]);
  94.  
  95.     if(isdigit(*argv[1])) {
  96.         for(ep = Delv; ep; ep = ep->next) {
  97.             if (ep == epr) {
  98.                 break;
  99.             }
  100.         }
  101.     } else {
  102.         char *name = cxallocw(argc,20);
  103.  
  104.         while(--argc > 0) {
  105.             strcat(name,*++argv);
  106.             strcat(name," ");
  107.         }
  108.         for(ep = Delv; ep; ep = ep->next) {
  109.             if(strnicmp(ep->file,name,strlen(name) - 1) == 0) {
  110.                 break;
  111.             }
  112.         }
  113.         xfree(name);
  114.     }
  115.     if(ep == 0) {
  116.         tputs(Notval);
  117.         return 0;
  118.     }
  119.     if(flag == TRUE) {
  120.         tputs("Use 'event drop'\n");
  121.         return 0;
  122.     }
  123.     return ep;
  124. }
  125.  
  126. /*----------------------------------------------------------------------*
  127. *  Check time for validity                                              *
  128. *-----------------------------------------------------------------------*/
  129. static int near
  130. chktime(char *from)
  131. {
  132.     int fh = 0, fm = 0;
  133.     char *cp = from;
  134.  
  135.     if(*cp++ == '+') {
  136.         return atoi(cp);
  137.     }
  138.     if((sscanf(from,"%d:%d",&fh,&fm)) == 2) {
  139.         fh = fh * 60 + fm;
  140.  
  141.         if(fh >= 0 && fh <= MINSPERDAY) {
  142.             return fh;
  143.         }
  144.     }
  145.     return -1;
  146. }
  147.  
  148. static char * near
  149. formtime(int t)
  150. {
  151.     static char buf[6];
  152.     int mins, hrs, ti = t;
  153.  
  154.     mins = ti % 60;
  155.     ti /= 60;
  156.     hrs = ti % 60;
  157.  
  158.     sprintf(buf,"%02d:%02d",hrs,mins);
  159.     return buf;
  160. }
  161.  
  162. /*----------------------------------------------------------------------*
  163. * this function is called every time a given window closes              *
  164. *-----------------------------------------------------------------------*/
  165. static void near
  166. deltimeout(void *p)
  167. {
  168.     Event *ep = (Event *)p;
  169.     struct tcb *tcb;
  170.  
  171.     ep->state = Wait;                   /* clear timer                  */
  172.  
  173.     if((tcb = check_tcp(ep)) != 0) {
  174.         reset_tcp(tcb);                 /* reset any connection         */
  175.     }
  176.     return;
  177. }
  178.  
  179. static void near
  180. delevent(Event *ep)
  181. {
  182.     char c;
  183.  
  184.     Current->ttystate.echo = Current->ttystate.edit = 0;
  185.     c = keywait("Warning! Running event, connection will be closed! Remove (y/n)? ",0);
  186.     Current->ttystate.echo = Current->ttystate.edit = 1;
  187.  
  188.     if(c == 'y') {
  189.         deltimeout(ep);                 /* reset running connection     */
  190.     }
  191. }
  192.  
  193. /*----------------------------------------------------------------------*
  194. * Build an event control block. This control block may have             *
  195. * different formats.                                                    *
  196. *-----------------------------------------------------------------------*/
  197. static int
  198. doEventadd(int argc,char **argv,void *p)
  199. {
  200.     int time;
  201.     Event *ep = mxallocw(sizeof(struct event));
  202.  
  203.     argc--;
  204.     argv++;
  205.  
  206.     if((time = chktime(*argv)) != -1) {        /* 1st arg time? */
  207.         ep->state = Atoneshot;
  208.         ep->from = time;
  209.         if(**argv == '+') {
  210.             ep->from += EMinute;
  211.         }
  212.         argc--;
  213.         argv++;
  214.     }
  215.     if((time = chktime(*argv)) != -1) {        /* 1st/2nd arg time? */
  216.         ep->state = Wait;
  217.         ep->to = time;
  218.         if(**argv == '+') {
  219.             ep->to += ep->from;
  220.         }
  221.         argc--;
  222.         argv++;
  223.     }
  224.     if(strchr(*argv,':') == NULL             /* 1st/2nd/3rd arg interval? */
  225.       && isdigit(**argv)
  226.       && (time = atoi(*argv)) > 0
  227.       && time <= MINSPERDAY) {
  228.         ep->state = Atinterval;
  229.         ep->interval = time;
  230.         argc--;
  231.         argv++;
  232.     }
  233.     if(argc < 0
  234.       || (ep->state == Atinterval
  235.         && (ep->interval == 0
  236.         || (ep->to && (ep->interval > (ep->to - ep->from)))))
  237.       || (ep->to && ep->to < ep->from)) {
  238.         tputs("Illegal time or syntax error\n");
  239.         xfree(ep);
  240.         return -1;
  241.     }
  242.     if(ep->state == Atinterval && !ep->from) {
  243.         ep->from = EMinute;
  244.     }
  245.     if((ep->minute = ep->from + ep->interval) > MINSPERDAY) {
  246.         ep->minute -= MINSPERDAY;
  247.     }
  248.     if(ep->state == Wait) {
  249.         if((ep->host = resolve(*argv)) == 0) {
  250.             tprintf(Badhost,*argv);
  251.             return -1;
  252.         }
  253.         ep->file = strxdup(*argv);
  254.     } else {
  255.         ep->file = cxallocw(argc + 1,20);
  256.  
  257.         while(argc-- > 0) {
  258.             strcat(ep->file,*argv++);
  259.             strcat(ep->file," ");
  260.         }
  261.     }
  262.     /*-------------------------------------------------------------------*
  263.     * seems that all the entries are correct, go connect the entry       *
  264.     *--------------------------------------------------------------------*/
  265.     ep->next = Delv;
  266.     Delv = ep;
  267.  
  268.     return 0;
  269. }
  270.  
  271. /*----------------------------------------------------------------------*
  272. *  Activate a previously suspended event. Must not be of type Auto      *
  273. *-----------------------------------------------------------------------*/
  274. static int
  275. doEactivate(int argc,char **argv,void *p)
  276. {
  277. Event *ep;
  278.  
  279.     if((ep = getep(argc,argv,TRUE)) != 0) {
  280.         if(ep->state == Suspended) {
  281.             ep->state = Wait;
  282.         }
  283.     }
  284.     return 0;
  285. }
  286.  
  287. /*----------------------------------------------------------------------*
  288. * drop an event from the list                                           *
  289. *-----------------------------------------------------------------------*/
  290. static int
  291. doEdrop(int argc,char **argv,void *p)
  292. {
  293. Event *ep, *epp = 0, *epr;
  294.  
  295.     if((ep = getep(argc,argv,FALSE)) != 0) {
  296.         if(ep->state == Running || ep->state == Autorun) {
  297.             delevent(ep);
  298.         }
  299.         epr = ep;
  300.  
  301.         for(ep = Delv; ep; ep = ep->next) {
  302.             if(epr == ep) {
  303.                 if(ep == Delv) {
  304.                     Delv = ep->next;
  305.                 } else {
  306.                     epp->next = ep->next;
  307.                 }
  308.                 xfree(ep->file);
  309.                 xfree(ep);
  310.                 return 0;
  311.             }
  312.             epp = ep;
  313.         }
  314.     }
  315.     return 0;
  316. }
  317.  
  318. /*----------------------------------------------------------------------*
  319. *  List event entries. Derived from the other list functions in the     *
  320. *  package.                                                             *
  321. *-----------------------------------------------------------------------*/
  322. static int
  323. doElist(int argc,char **argv,void *p)
  324. {
  325.     Event *ep = 0;
  326.     static char s[] = "       ";
  327.  
  328.     /*-------------------------------------------------------------------*
  329.     * display events                                                     *
  330.     *--------------------------------------------------------------------*/
  331.     tputs("&EVCB  Status    From   To     Next   Time   Cmd\n");
  332.  
  333.     for(ep = Delv; ep; ep = ep->next)  {
  334.         tprintf("%-7x",ptol(ep));
  335.         tprintf("%-10s",Dsstring[ep->state]);
  336.  
  337.         if((ep->from && ep->state != Atinterval)
  338.           || (ep->state == Atinterval && ep->to)) {
  339.             tprintf("%-7s",formtime(ep->from));
  340.         } else {
  341.             tputs(s);
  342.         }
  343.         if(ep->to) {
  344.             tprintf("%-7s",formtime(ep->to));
  345.         } else {
  346.             tputs(s);
  347.         }
  348.         if(ep->state == Atinterval) {
  349.             tprintf("%-7s%-7d",formtime(ep->minute),ep->interval);
  350.         } else {
  351.             tputs(s);
  352.             tputs(s);
  353.         }
  354.         tprintf("%s\n",ep->file);
  355.     }
  356.     return 0;
  357. }
  358.  
  359. /*----------------------------------------------------------------------*
  360. *  Stop a running event, but don't remove                               *
  361. *-----------------------------------------------------------------------*/
  362. static int
  363. doEstop(int argc,char **argv,void *p)
  364. {
  365. Event *ep;
  366.  
  367.     if((ep = getep(argc,argv,TRUE)) != 0) {
  368.         if(ep->state == Running) {
  369.             delevent(ep);
  370.         }
  371.     }
  372.     return 0;
  373. }
  374.  
  375. /*----------------------------------------------------------------------*
  376. * Suspend an event                                                      *
  377. *-----------------------------------------------------------------------*/
  378. static int
  379. doEsuspend(int argc,char **argv,void *p)
  380. {
  381. Event *ep;
  382.  
  383.     if((ep = getep(argc,argv,TRUE)) != 0) {
  384.         if(ep->state == Running) {
  385.             delevent(ep);
  386.         }
  387.         ep->state = Suspended;
  388.     }
  389.     return 0;
  390. }
  391.  
  392. int
  393. doevent(int argc,char **argv,void *p)
  394. {
  395.     struct cmds Evtcmds[] = {
  396.         {"add",      doEventadd,  0, 3, "event add <hh:mm>|<interval> <command> [arg]"},
  397.         {"activate", doEactivate, 0, 2, "event activate <evcb>"},
  398.         {"drop",     doEdrop,     0, 2, "event drop <evcb>"},
  399.         {"list",     doElist,     0, 0, NULLCHAR},
  400.         {"stop",     doEstop,     0, 2, "event stop <evcb>"},
  401.         {"suspend",  doEsuspend,  0, 2, "event suspend <evcb>"},
  402.         {NULLCHAR,   NULLFP,      0, 0, NULLCHAR}
  403.     };
  404.     return subcmd(Evtcmds,argc,argv,p);
  405. }
  406.  
  407.  
  408. /*----------------------------------------------------------------------*
  409. * The event process. This process is called every minute by the         *
  410. * statline process. The only parameter passed is the actual             *
  411. * minute. (Note that the alert/pwait pair has been changed to accept    *
  412. * a void * systemwide, which give a more flexible way to pass           *
  413. * more than just an integer information
  414. *-----------------------------------------------------------------------*/
  415. void
  416. event(int i,void *v1,void *v2)
  417. {
  418.     Event *ep;
  419.     Dstate state;
  420.  
  421.     Eproc = Curproc;
  422.  
  423.     for(; ;) {
  424.         if(EVwait != 0) {
  425.             EVwait--;
  426.         }
  427.         EMinute = (int)pwait(&state);
  428.         EVwait++;
  429.  
  430.         /*--------------------------------------------------------------*
  431.         * scan structures for any job to to                             *
  432.         *---------------------------------------------------------------*/
  433.         for(ep = Delv; ep; ep = ep->next) {
  434.             switch (ep->state) {
  435.             case Wait:
  436.                 if(EMinute >= ep->from && EMinute < ep->to) {
  437.                     /* got one */
  438.                     ep->state = Running;
  439.                     smtptick((void *)ep->host);
  440.                     pwait(NULL);
  441.                 }
  442.                 break;
  443.             case Running:
  444.                 if(ep->state == Running && ep->to < EMinute) {
  445.                     deltimeout(ep);
  446.                     pwait(NULL);
  447.                 }
  448.                 break;
  449.             case Atinterval:
  450.                 if(ep->from && ep->to
  451.                   && (EMinute < ep->from || EMinute >= ep->to)) {
  452.                     ep->minute = ep->from;
  453.                     continue;
  454.                 }
  455.             default:
  456.                 if(EMinute == ep->minute) {
  457.                     char *cp = strxdup(ep->file);
  458.                     log(-1,9985,cp);
  459.                     cmdparse(Cmds,cp,0);
  460.                     xfree(cp);
  461.  
  462.                     if(ep->state == Atinterval) {
  463.                         if((ep->minute += ep->interval) > MINSPERDAY)
  464.                             ep->minute -= MINSPERDAY;
  465.                     }
  466.  
  467.                 }
  468.                 break;
  469.             }
  470.         }
  471.     }
  472. }
  473.  
  474.